/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Panaderia;

import java.util.logging.Level;
import java.util.logging.Logger;


public class Coche extends Thread {
    
    public Carretera carretera;
    
    //Movimientos permitidos
    public static enum Sentido {
        DERECHA,
        IZQUIERDA
    };
    
    //Coche
    public String coche;
    //Posición del coche
    public int pos;
    //¿Hacia donde va el coche?
    public Sentido sentido;
    //¿Quiero pasar?
    public boolean quieroPasar;
    //Te toca...
    public boolean esMiTurno;
    //¿Coche en movimiento?
    public boolean enMovimiento;

    public int velocidad;
    
    public Coche(String nombreCoche,Carretera carretera, Sentido sentido){
        
        this.coche = nombreCoche;
        this.carretera = carretera;
        this.sentido = sentido;
        this.velocidad = 1;
        if (this.sentido == Sentido.DERECHA) { 
            pos = carretera.POS_MIN;
        } else if (this.sentido == Sentido.IZQUIERDA) {
            pos = carretera.POS_MAX;
        }
        carretera.listaCoches.add(this);
    }
    
    private Coche() {
        super();
    }

    //Getters&Setters
    public int getPos() {
        return pos;
    }

    public void setPos(int pos) {
        this.pos = pos;
    }
    
    public void mover (){
        
        if(Sentido.DERECHA == this.sentido) {
            if(this.pos >= carretera.POS_MAX) {
                this.sentido = Sentido.IZQUIERDA;
            } else {
                this.pos++;
            }
        } else if (Sentido.IZQUIERDA == this.sentido) {
            if(this.pos <= carretera.POS_MIN) {
                this.sentido = Sentido.DERECHA;
            } else {
                this.pos--;          
            }
        }
    }

    public void terminar() {
        this.enMovimiento = false;
    }
    
    @Override
    public void run(){
            this.enMovimiento = true;
        while (this.enMovimiento) {
                try {
                    if (this.pos < this.carretera.getInicioEstrechamiento() ||
                            this.pos > this.carretera.getFinEstrechamiento() ) {
                        this.mover();
                    } else {
                        Coche otroCoche;
                        int index = carretera.listaCoches.indexOf(this);
                        if (index == carretera.listaCoches.size()-1) {
                            otroCoche = carretera.listaCoches.get(0);
                        } else {
                            otroCoche = carretera.listaCoches.get(index+1);
                        }
                        System.out.println(this.toString() +" Otro coche: " + otroCoche.toString());
                        quieroPasar = true;
                        while (otroCoche.quieroPasar) {
                            if (!esMiTurno){
                                System.out.println(this.toString() + " No es mi turno");
                                quieroPasar = false;
                            }
                            int count = 0;
                            while(!esMiTurno){ 
                                Thread.sleep (100);
                                if (++count % 30 == 0) {
                                    System.out.println("Esperando .. " + toString());
                                }
                            } // espera activa
                            quieroPasar = true;
                        }
                        
                        while (this.pos >= this.carretera.getInicioEstrechamiento() &&
                            this.pos <= this.carretera.getFinEstrechamiento()) {
                            
                            this.mover();
                            System.out.println(this.toString());
                            Thread.sleep((long) Math.floor(1000/velocidad));
                        }
                        
                        esMiTurno = false;
                        quieroPasar = false;
                        otroCoche.esMiTurno=true;
                        System.out.println(otroCoche.toString());
                    }

                    System.out.println(this.toString());
                    Thread.sleep((long) Math.floor(1000/velocidad));;
                    
                } catch (InterruptedException ex) {
                    Logger.getLogger(Coche.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
        
                        /*
                flag = true;
                while (flag == true) {
                if (turno != 0) {
                flag = false;
                while (turno != 0) {
                // busy wait
                }
                flag = true;
                }
                }
                // critical section
                turno    = 1;
                flag = false;
                 */ 
        

        
    }
    
    public String toString (){

        return "Coche " + this.coche + " (Pos: " + this.pos + " - QuieroPasar: " 
                + quieroPasar + " EsMiTurno: " + esMiTurno + ") ";
        
    }
    
    @Override
    public Object clone () throws CloneNotSupportedException {
        Coche clon = new Coche();
        clon.coche = this.coche;
        clon.carretera = this.carretera;
        clon.pos = this.pos;
        clon.sentido = this.sentido;
        clon.velocidad = this.velocidad;
        
        carretera.cambiarCoche(this, clon);
        
        return clon;
    }
}
